<template>
  <view :class="ns.b()">
    <template v-if="items.length === 0">{{ emptyText }}</template>
    <template v-else>
      <template v-for="(item, index) in items" :key="index">
        {{ index !== 0 ? textSeparator : null }}
        <view
          :class="[ns.e('item'), item.textCls ? item.textCls : null]"
          :style="
            item.color
              ? ns.cssVarBlock({
                  'item-color': `${item.color}`,
                })
              : null
          "
        >
          <i-biz-icon
            v-if="showMode !== 'TEXT' && !!item.sysImage"
            :icon="item.sysImage"
          />
          {{ showMode !== "ICON" && item.text }}
        </view>
      </template>
    </template>
  </view>
</template>
<script lang="ts">
export default {
  options: {
    addGlobalClass: true,
    virtualHost: true,
    styleIsolation: "shared"
  }
}
</script>
<script setup lang="ts">
import { computed, ref, watch } from "vue";
import {
  calcThresholdRange,
  CodeListItem,
  useCalcOrMode,
  useCalcOrModeType,
} from "@ibiz-template/runtime";
import { useNamespace } from "@/use";
import { isNumber } from "lodash-es";
import { isNil } from "ramda";
import { codeListProps } from "./i-biz-code-list";

interface EditorEmit {
  (name: "infoTextChange", value: string): void;
}

const props = defineProps(codeListProps);
const emit = defineEmits<EditorEmit>();

const ns = useNamespace("code-list");
const items = ref<IData[]>([]);
const textSeparator = props.codeList?.textSeparator || "、";
const valueSeparator = props.codeList?.valueSeparator || ",";
const emptyText =
  props.codeList.emptyText === ibiz.i18n.t("common.undefined")
    ? "- - -"
    : props.codeList.emptyText;
const currentMode = computed(() => {
  if (props.codeList && props.codeList.orMode) {
    return props.codeList.orMode;
  }
  return "STR";
});

const calcOrMode: useCalcOrModeType = useCalcOrMode(currentMode.value);

watch(items, (newVal) => {
  let infoText = "";
  if (newVal.length > 0) {
    infoText = newVal.map((item) => item.text).join(textSeparator);
  }
  emit("infoTextChange", infoText);
});

const findCodeListItem = (
  codelist: CodeListItem[] | undefined,
  value: string | number
) => {
  if (codelist) {
    const { thresholdGroup } = props.codeList;
    if (thresholdGroup && isNumber(Number(value))) {
      const findItem = calcThresholdRange(codelist, Number(value));
      if (findItem) {
        return findItem;
      }
    }
    const findItem = codelist.find((item) => item.value == value);
    if (findItem) {
      return findItem;
    }
    for (let i = 0; i < codelist.length; i++) {
      const childrenItem = findCodeListItem(
        codelist[i].children,
        value
      ) as CodeListItem;
      if (childrenItem) {
        return childrenItem;
      }
    }
  }
};

watch(
  [() => props.codeListItems, () => props.value],
  ([codeListItems, value], [_oldCodeListItems, _oldValue]) => {
    if (isNil(value) || value === "") {
      // 空值置空
      items.value = [];
    } else {
      // 非空值解析代码表
      let values: string[] | number[] = [];
      const { getSelectArray } = calcOrMode;
      const arr = getSelectArray(
        value,
        props.codeList,
        codeListItems as readonly CodeListItem[],
        valueSeparator,
        props.codeList.codeItemValueNumber
      );
      if (arr) {
        values = arr as string[] | number[];
      }
      items.value = values.map((val) => {
        const findItem = findCodeListItem(codeListItems, val);
        let codeValue = val;
        if (props.convertToCodeItemText && findItem?.text) {
          codeValue = findItem.text;
        } else {
          // 未转换代码表文本时支持转换值格式化、单位
          const { valueFormat, unitName } = props;
          if (valueFormat) {
            codeValue = ibiz.util.text.format(`${codeValue}`, valueFormat);
          }
          if (unitName) {
            codeValue += unitName;
          }
        }
        return {
          text: codeValue,
          color: findItem?.color,
          textCls: findItem?.textCls,
          sysImage: findItem?.sysImage,
        };
      });
    }
  },
  { immediate: true }
);
</script>
<style lang="scss">
@include b(code-list) {
  @include flex(row, flex-start, center);

  flex-wrap: wrap;

  @include e(item) {
    color: getCssVar("code-list", "item-color");
    @include flex(row, flex-start, center);
  }

  @include b(icon) {
    display: inline-flex;
    padding-right: getCssVar(spacing, tight);
  }
}
</style>
